package org.raymond.iworks.gateway.controller;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.raymond.iworks.apis.common.Result;
import org.raymond.iworks.apis.vo.test.TestParamVO;
import org.raymond.iworks.core.constants.SecurityComponets;
import org.raymond.iworks.gateway.utils.SignUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
public class TestController {
    private static final RSA rsa = SecurityComponets.DEFAULT_ENCRYPTOR;

    @Autowired
    private SignUtil signUtil;

    @PostMapping("/test/params")
    @ResponseBody
    /**
     * 支持postman调用login接口,获取加密参数,并获取加密后的登陆参数
     * 1. 在postman的headers中添加3个参数: CRYPTO(key), IV(iv), SIGN(随意). 注意key和iv的长度
     * 2. 在postman的body(raw)中输入input
     * 3. send to login
     */
    public Result testParams(@RequestBody TestParamVO paramVO){
        String publicKeyBase64 = paramVO.getPublicKey();
        if(StringUtils.isBlank(publicKeyBase64)){
            publicKeyBase64 = rsa.getPublicKeyBase64();
        }
        String oriKey = paramVO.getKey();
        String oriIv = paramVO.getIv();
        Map<String, Object> input = paramVO.getInput();
        String inputJsonStr = JSONUtil.toJsonStr(input);
        String signPlain = signUtil.signMap(input);
        log.info("publicKey:{}, key:{}, iv:{}, input:{}, sign:{}", publicKeyBase64, oriKey, oriIv, inputJsonStr, signPlain);

        String encryptedKey = rsa.encryptBase64(oriKey, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
        String encryptedIv = rsa.encryptBase64(oriIv, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);

        AES aes = new AES("CBC", "PKCS7Padding", oriKey.getBytes(StandardCharsets.UTF_8), oriIv.getBytes(StandardCharsets.UTF_8));
        String encryptedSign = aes.encryptBase64(signPlain);

        String inputEncryptedStr = aes.encryptBase64(inputJsonStr, CharsetUtil.CHARSET_UTF_8);
        Map<String, Object> testParams = new HashMap<>();
        testParams.put("key", encryptedKey);
        testParams.put("iv", encryptedIv);
        testParams.put("sign", encryptedSign);
        testParams.put("input", inputEncryptedStr);

        testParams.put("plainKey", oriKey);
        testParams.put("plainIv", oriIv);
        return Result.success(testParams);
    }
}
